package compilers;

import java.util.List;
import java.util.Stack;

/**
 * @program: javase
 * @description:
 * @author: lld
 * @create: 2021-04-29 16:18
 **/
public class SyntaxAnalysis {

    private List<String> exp;
    private Stack<String> operandStack;
    private Stack<String> operatorStack;
    private ComperOperator cOperator;

    public SyntaxAnalysis(List<String> exp) {
        super();
        Init();
        this.exp = exp;
    }

    private void Init() {
        operatorStack = new Stack<String>();
        operandStack = new Stack<String>();
        cOperator = new ComperOperator();
    }

    public boolean IfOperand(String s) {
        char c = s.charAt(0);
        if (c >= '0' && c <= '9' || c == '.') {
            return true;
        }
        return false;
    }

    public boolean IfOperator(String s) {
        char c = s.charAt(0);
        switch (c) {
            case '+':
            case '-':
            case '*':
            case '/':
            case '(':
            case ')':
            case '#':
                return true;

            default:
                break;
        }
        return false;
    }

    public void analysis() {

        double numA;
        double numB;
        double result;
        String token;

        for (int i = 0; i < exp.size(); i++) {
            if (i == 1 || i == 2) {
                continue;
            }
            token = exp.get(i);

            if (IfOperand(token)) {
                operandStack.push(token);
            } else if (IfOperator(token)) {
                if (operatorStack.isEmpty()) {
                    operatorStack.push(token);
                } else {
                    switch (cOperator.comperOperator(operatorStack.peek().charAt(0), token.charAt(0))) {
                        case '<':  //token优先级高，入栈
                            operatorStack.push(token);
                            break;
                        case '=':  //去括号，#号
                            operatorStack.pop();
                            break;
                        case '>':  //取出运算符运算
                            if (operandStack.isEmpty()) {
                                System.out.println("表达式不正确！");
                                return;
                            } else {
                                numB = Double.parseDouble(operandStack.pop());
                            }
                            if (operandStack.isEmpty()) {
                                System.out.println("表达式不正确！");
                                return;
                            } else {
                                numA = Double.parseDouble(operandStack.pop());
                            }

                            switch (operatorStack.pop().charAt(0)) {
                                case '+':
                                    result = numA + numB;
                                    break;
                                case '-':
                                    result = numA - numB;
                                    break;
                                case '*':
                                    result = numA * numB;
                                    break;
                                case '/':
                                    if (numB == 0) {
                                        return;
                                    } else {
                                        result = numA / numB;
                                    }
                                    break;
                                default:
                                    System.out.println("表达式不正确！");
                                    return;
                            }
                            operandStack.push(result + "");
                            break;
                        case '?':
                            System.out.println("表达式不正确！");
                            return;
                    }
                }
            }
        }
        result = Double.parseDouble(operandStack.pop());
        if (!operandStack.isEmpty() || !operatorStack.isEmpty()) {
            System.out.println("表达式不正确！");
            return;
        } else {
            System.out.println(exp.get(1) + exp.get(2) + result);
        }
    }
}
